4W - 번외 - 트레이싱용 심플 메시 서버 개발
개요
이번 문서는 조금 예외로, 트레이싱 관련 실습을 하기 위해 내가 개발한 서버에 대한 내용을 간략하게 정리한다.
책의 예시를 그냥 따라해보는데, 뭔가뭔가 너무 아쉬운 느낌이 들었다.
기껏 트레이싱하는데 기왕이면 여러 서버를 거치는 트레이스를 간단하게 확인할 방법이 있으면 좋겠다고 생각했다.
그러다가 떠오른 생각이, 순전히 메시 내부에서 트레이싱을 위해 가동되는 테스트 서버가 있으면 좋겠다 싶었다.
가령 http://a/b/c
라고 요청을 보내면 a 서버가 요청을 받아서 이걸 http://b/c
로 보내고, b 서버는 이걸 또 http://c
로 보내는 방식으로 간단하게 url에 설정만 하는 것으로 트래픽을 마구 포워딩할 수 있는 테스트 환경을 구축하면, 트레이싱을 확인하는데 매우 유용할 것이다.
간단 정리
클러스터에서 활용할 수 있는 단일 웹 서버 바이너리를 개발한다.
이 웹 서버들은 클러스터 내에서 고유한 네트워크 식별자를 통해 접근할 수 있으며, 이를 기반으로 서버 간 통신을 할 수 있다.
핵심 기능 정의
- 사용자는 임의의 웹서버에 임의의 서브패스를 넣어 요청을 날릴 수 있다.
- 웹서버는 요청을 받고 서브패스의 값을 추출하여 자신이 요청을 날려야할 후속 웹 서버를 결정한다.
- 후속 웹 서버에 요청을 날리고, 돌아온 응답을 합쳐서 자신의 응답에 반영한다.
- 서브패스에 더 이상 값이 없다면 웹서버는 바로 응답을 반환한다.
- 웹서버는
~
를 구분자로 자신이 요청을 날릴 웹 서버를 구분하여 복수의 요청을 날릴 수 있다.
간단하게 사용자의 요청의 예시 플로우를 그려보았다.
A/B~C/D
로 요청을 날리면 A서버로 요청이 날아간다.- A서버는 서브 패스로
B~C/D
를 읽어내고, 여기에서~
를 구분자로 사용해 B와 C서버 후속 요청을 날린다. - B, C 서버는 다시금 서브 패스로 D를 받기 때문에 또 D에 요청을 날린다.
url을 기반으로 그냥 후속 서버에 추가 요청을 날릴 수 있다면, 원하는 대로 서버를 띄우고 해당 서버끼리 통신을 하게 하는 트래픽을 매우 쉽게 만들어낼 수 있다.
위 예시에서는 4개의 서버를 두었지만 서버를 얼마든지 늘려도 되고, 서버 간 트래픽이 순환하게 하는 것도 가능하다.
추가 기능
몇 가지 기능을 추가적으로 생각하고 정리해두었다.
실제 기능 구현을 한 것도 있고, 안 한 것도 있다.
- 환경 변수로 설정 주입(구현)
- 서버의 주소, 포트 등의 값을 컨테이너 환경 변수로 넣고 이를 기반으로 서버의 설정을 커스텀할 수 있다.
- 일정 시간 지연 발생(구현)
- 비동기 요청(미구현)
- 병렬적인 요청을 비동기로도 세팅할 수 있도록 한다.
- 사실 이 부분은 구체화가 안 된 것이, 처음에는 쿼리 파라미터로 전체 흐름을 세팅할 수 있게 할까 하다 말았다.
- 헬름 세팅(미구현)
- 한 서버를 추가할 때마다 비슷한 양식을 반복적으로 작성해야 하는데, 아예 차트로 템플릿화시켜 세팅을 더 간편하게 할 수 있도록 한다.
- 경로 상세 설정(미구현)
- 현재의 기능은 일방향적으로 작성하는데, 요청 분기가 일어나는 지점이 있으면 후속 서버는 분기된 서버마다 요청을 받게 된다.
- 좀 더 DAG 그래프를 자유롭게 만들 수 있도록 하는 url 세팅 방법이 당장 생각나지 않아 진행하지 않았다.
개발
개발은 매우 단순하게 진행했다.
uv를 이용해 환경 세팅을 하고 FastAPI로 서버를 구성했다.
모든 서버는 요청을 처리할 때 자신의 호스트 값, 그리고 자신이 요청을 처리하는데 걸린 시간을 응답으로 반환한다.
환경 변수로 지연 시간이 전달되면 해당 값만큼 시간이 지연되도록 돼있다.
후속 서버로 간 요청은 next_node
필드에 담겨 결과적으로 처음 요청을 날린 클라이언트는 모든 서버의 요청을 받아볼 수 있게 된다.
환경 변수에서 값을 받아오는 코드는 이렇게 생겼다.
비동기 처리를 하려고 추가한 변수도 있는데, 실제로 사용하지는 않았다.
추가적으로 조금이나마 활용해먹을 상황이 있을 것 같아서 프로메테우스 메트릭 계측 라이브러리를 세팅했다.
확인
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
WORKDIR /app
ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-dev
ADD . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
ENV PATH="/app/.venv/bin:$PATH"
CMD ["uv", "run", "main.py"]
도커파일은 오텔 공식 문서에 나온 내용을 그대로 옮겨 넣었다.
docker build -t zerotay/simple-mesh:1.0.0 .
docker push zerotay/simple-mesh:1.0.0
급하게 세팅하다보니 멀티 플랫폼 빌드는 해두지 않았는데, 나중에 요구사항이 있다며 추가하겠다.
apiVersion: v1
kind: Service
metadata:
name: a
spec:
selector:
app: a
ports:
- protocol: TCP
port: 80
targetPort: 9090
---
apiVersion: v1
kind: Pod
metadata:
name: a
annotations:
instrumentation.opentelemetry.io/inject-python: "true"
labels:
app: a
spec:
containers:
- name: a
image: zerotay/simple-mesh:1.1.0
env:
- name: HOST
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: PORT
value: "9090"
이미지가 올라갔으니, 이제 관련 양식을 만들어서 테스트해보면 된다!
위와 같은 방식으로 몇 개 리소스를 만들어본다.
나는 a,b,c 서비스를 세우고 요청을 날려보았다.
a는 0.5초, b는 1초, c는 1.5초의 지연이 발생하도록 세팅돼있다.
그래서 합산한 값이 그대로 표시되는 것을 확인할 수 있다.
참고로 로그는 이런 식으로 남았다.
fastapi에서 로그 설정하는 방법이 잘 기억이 안 나서 대충 세팅하니 내 커스텀 로그랑 겹쳐서 보이고 있다.
아무튼 일단 자신의 호스트 정보를 남기고, 어디로 트래픽을 보내야 할지 명시한다.
결론
결론이랄 건 없고.. 일단 간단하게 중첩된 트래픽을 발생시킬 수 있는 환경을 만들게 돼서 상당히 만족스럽다.
나중에 조금 더 발전시켜서 다양한 상황을 테스트하는데 유용하게 사용할 수 있을 것으로 기대한다.
참고로 코드는 깃헙에 올려두었다.
이전 글, 다음 글
다른 글 보기
이름 | index | noteType | created |
---|---|---|---|
1W - 서비스 메시와 이스티오 | 1 | published | 2025-04-10 |
1W - 간단한 장애 상황 구현 후 대응 실습 | 2 | published | 2025-04-10 |
1W - Gateway API를 활용한 설정 | 3 | published | 2025-04-10 |
1W - 네이티브 사이드카 컨테이너 이용 | 4 | published | 2025-04-10 |
2W - 엔보이 | 5 | published | 2025-04-19 |
2W - 인그레스 게이트웨이 실습 | 6 | published | 2025-04-17 |
3W - 버츄얼 서비스를 활용한 기본 트래픽 관리 | 7 | published | 2025-04-22 |
3W - 트래픽 가중치 - flagger와 argo rollout을 이용한 점진적 배포 | 8 | published | 2025-04-22 |
3W - 트래픽 미러링 패킷 캡쳐 | 9 | published | 2025-04-22 |
3W - 서비스 엔트리와 이그레스 게이트웨이 | 10 | published | 2025-04-22 |
3W - 데스티네이션 룰을 활용한 네트워크 복원력 | 11 | published | 2025-04-26 |
3W - 타임아웃, 재시도를 활용한 네트워크 복원력 | 12 | published | 2025-04-26 |
4W - 이스티오 메트릭 확인 | 13 | published | 2025-05-03 |
4W - 이스티오 메트릭 커스텀, 프로메테우스와 그라파나 | 14 | published | 2025-05-03 |
4W - 번외 - 트레이싱용 심플 메시 서버 개발 | 16 | published | 2025-05-03 |
4W - 오픈텔레메트리 기반 트레이싱 예거 시각화, 키알리 시각화 | 15 | published | 2025-05-03 |
5W - 이스티오 mTLS와 SPIFFE | 17 | published | 2025-05-11 |
5W - 이스티오 JWT 인증 | 18 | published | 2025-05-11 |
5W - 이스티오 인가 정책 설정 | 19 | published | 2025-05-11 |
6W - 이스티오 설정 트러블슈팅 | 20 | published | 2025-05-18 |
6W - 이스티오 컨트롤 플레인 성능 최적화 | 21 | published | 2025-05-18 |
8W - 가상머신 통합하기 | 22 | published | 2025-06-01 |
8W - 엔보이와 iptables 뜯어먹기 | 23 | published | 2025-06-01 |
9W - 앰비언트 모드 구조, 원리 | 24 | published | 2025-06-07 |
9W - 앰비언트 헬름 설치, 각종 리소스 실습 | 25 | published | 2025-06-07 |
7W - 이스티오 메시 스케일링 | 26 | published | 2025-06-09 |
7W - 엔보이 필터를 통한 기능 확장 | 27 | published | 2025-06-09 |
관련 문서
이름 | noteType | created |
---|---|---|
Python | knowledge | 2025-05-02 |
uv | knowledge | 2025-05-02 |
Ansible | knowledge | 2025-06-10 |